<?php

/**
 * uniBoard ACP Style Import Page
 *
 * Light and fast forum solution for web 2.0-like communities.
 *
 * @package		uniBoard
 * @author		Rafał Pitoń
 * @license		http://www.gnu.org/licenses/gpl-3.0.html
 * @since		Version 0.1
 * 
 * ------------------------------------------------------------------------
 * 
 * $Date: 2010-09-15 17:35:38 +0000 (Wed, 15 Sep 2010) $
 * $Revision: 61 $
 * $Author: rafio.xudb@gmail.com $
 */

// ------------------------------------------------------------------------

class action_imp_style{
	
	/**
	 * Main class pointer
	 *
	 * @var object
	 */
	
	private $appCore		= NULL;
	
	/**
	 * Style API
	 *
	 * @var object
	 */
	
	private $api			= NULL;
	
	/**
	 * Imagesets list
	 *
	 * @var array
	 */
	
	private $imagesets		= array();
	
	// ------------------------------------------------------------------------

	/**
	 * Initialise Action
	 *
	 * @param object $appCore
	 */
	
	function __construct( $appCore){
		
		// Store appCore pointer
		$this -> appCore = $appCore;

		// Start Style API
		$this -> api = new api_style( $appCore);

		// Collect imagesets
		$appCore -> db -> query( 'SELECT imageset_id, imageset_name
		FROM ' . DB_PREFIX . 'imagesets
		ORDER BY imageset_name');
		
		// Parse result
		while ( $imageset_result = $appCore -> db -> fetch_array())
		{
			// Add imageset to cache store
			$this -> imagesets[$imageset_result[0]] = htmlspecialchars( $imageset_result[1]);
		}
		
		// Upload?
		if ( $appCore -> _POST( 'upload') == 1)
		{
			// Import imageset
			$this -> doImport();	
		}
		else
		{
			// Draw form
			$this -> drawForm();
		}
		
	}
	
	// ------------------------------------------------------------------------
	
	/**
	 * Performs import
	 *
	 */
	
	function doImport(){
		
		// Try-catch
		try
		{
			// Set Parent
			$this -> api -> setStyleParent( $this -> appCore -> _POST( 'style_parent'));
			
			// Set new imageset
			if ( isset( $this -> imagesets[ $this -> appCore -> _POST( 'style_imageset')]))
			{
				$this -> api -> setImagesetId( $this -> appCore -> _POST( 'style_imageset'));	
			}
			else
			{
				throw new exc_small( $this -> appCore -> lang['acp_style_not_found']);
			}
			
			// Error in api?
			if ( $this -> api -> error)
			{
				throw new exc_small( $this -> api -> last_error);				
			}
			
			// Create file upload
			$data_file = new api_file_upload( $this -> appCore, 'data_file');
			
			// Configure uploaded
			$data_file -> setExtensions( array( '.xml', '.xml.gz'));
			$data_file -> setUploadSize( 12288);
			
			// Catch file
			$data_file -> catchFile();
			
			// Api has error?
			if ( $data_file -> error)
			{
				// Trow exception
				throw new exc_small( $data_file -> last_error);
			}
				
			// Detect if we uploaded file is GZIP compressed
			if ( strtolower( substr( $data_file -> getFileName(), strlen( $data_file -> getFileName()) - 7)) == '.xml.gz')
			{
				// Uncompress file
				if ( function_exists( 'gzfile'))
				{
					$data_file = join( '', gzfile( $data_file -> getFilePath()));
				}
				else
				{
					// Trow exception
					throw new exc_small( $this -> appCore -> lang['acp_style_import_gzip_not_avaiable']);
				}
			}
			else
			{
				// Simply load XML file contents
				$data_file = file_get_contents( $data_file -> getFilePath());
			}
			
			// We will handle errors
			libxml_use_internal_errors(false);
			
			// Create xml data file
			@$data = simplexml_load_string( $data_file);
			
			// Error?
			if ( $data === false)
			{
				// Trow exception
				throw new exc_small( $this -> appCore -> lang['acp_import_xml_corrupted']);
			}
			
			// Data is valid?
			if ( !isset( $data -> style_data) || !isset( $data -> style_data -> style_name) || !isset( $data -> style_data -> style_css) || !isset( $data -> style_templates))
			{
				throw new exc_small( $this -> appCore -> lang['acp_import_xml_corrupted']);
			}
			
			// Fill it with data
			$this -> api -> setStyleName( base64_decode( $data -> style_data -> style_name));
			$this -> api -> setStyleCss( base64_decode( $data -> style_data -> style_css));
			$this -> api -> setStyleJs( base64_decode( $data -> style_data -> style_js));
			
			// Additional fields
			if ( isset( $data -> style_data -> style_author))
			{
				$this -> api -> setStyleAuthor( base64_decode( $data -> style_data -> style_author));
			}
			
			if ( isset( $data -> style_data -> style_email))
			{
				$this -> api -> setStyleEmail( base64_decode( $data -> style_data -> style_email));
			}
			
			if ( isset( $data -> style_data -> style_www))
			{
				$this -> api -> setStyleWww( base64_decode( $data -> style_data -> style_www));
			}
			
			// Api got incorrect settings?
			if ( $this -> api -> error)
			{	
				// API has incorrect data from XML
				throw new exc_small( $this -> appCore -> lang['acp_import_xml_corrupted']);
			}
			
			// Create api
			$this -> api -> saveData();
			
			// Create new directory for api
			class_files::newDir( STYLES_DATA_PATH . 'style_' . $this -> api -> style_id);
			
			// Templates Insert
			$insert_sql = array();
			
			// Reiterate Templates
			foreach ( $data -> style_templates -> template as $tpl_data)
			{
				// Template has correct data?
				if ( isset( $tpl_data -> template_group) && isset( $tpl_data -> template_name) && isset( $tpl_data -> template_code))
				{
					// Decode data
					$template_group = base64_decode( $tpl_data -> template_group);
					$template_name = base64_decode( $tpl_data -> template_name);
					$template_code = base64_decode( $tpl_data -> template_code);
					
					// File content is good?
					if ( isset( $template_group[0]) && isset( $template_name[0]) && mb_strlen( $template_group) < 256 && mb_strlen( $template_name) < 256)
					{
						// Add file to massinsert
						$insert_sql[] = '\'' . $this -> api -> style_id . '\', \''. $this -> appCore -> db -> strEscape( $template_group) . '\', \''. $this -> appCore -> db -> strEscape( $template_name) . '\', \''. $this -> appCore -> db -> strEscape( $template_code) . '\'';
							
					}
				}
			}
			
			// Multiple insert?
			if ( !empty( $insert_sql))
			{
				$this -> appCore -> db -> multipleInsert( 'style_id, template_group, template_name, template_code', $insert_sql, 'styles_templates');
			}
			
			// Create CSS and JS files
			file_put_contents( STYLES_DATA_PATH . 'style_' . $this -> api -> style_id . '.css', class_cache::makeFileStamp( 'STYLE ' . $this -> api -> style_id . ' CSS FILE', false) . str_ireplace( array( '{IMAGES_DIR}', '{BLUEPRINT_DIR}'), array( 'imageset_' . $this -> api -> imageset_id, CSS_FRAMEWORK_PATH), $this -> api -> style_css));
			file_put_contents( STYLES_DATA_PATH . 'jscript_' . $this -> api -> style_id . '.js', class_cache::makeFileStamp( 'STYLE ' . $this -> api -> style_id . ' JAVASCRIPT FILE', false) . $this -> api -> style_js);
			
			// Run resynchroniser
			$this -> resynchStyle( $this -> api -> style_id);
				
			// Create Log
			$this -> appCore -> logAdmin( 'log_admin_imported_style', htmlspecialchars( $this -> api -> style_name));
			
			// Stuff added, trow user to styles list
			$this -> appCore -> output -> drawRedirect( $this -> appCore -> adminLink( 'act=styles'), $this -> appCore -> lang['acp_style_imported']);			
		}
		catch ( exc_small $error)
		{
			// Draw error
			$this -> appCore -> output -> error( $error -> message, $this -> appCore -> lang['acp_import_imageset']);
			
			// Repeat form
			$this -> drawForm();
		}
		
	}
	
	// ------------------------------------------------------------------------
	
	/**
	 * Draws import form
	 *
	 */
	
	function drawForm(){
		
		// Start output buffer
		ob_start();
		
		// Load fields templates
		$this -> appCore -> templates['form_inputs'] = new tpl_form_inputs( $this -> appCore);
		
		// Open Form
		echo $this -> appCore -> output -> openForm( $this -> appCore -> adminLink( 'act=imp_style'), '', true);
		echo $this -> appCore -> drawHidden( 'upload', 1);
		
		// Open Block
		echo $this -> appCore -> output -> openFormBlock();
		
		// Draw Field
		echo $this -> appCore -> output -> formItem( $this -> appCore -> lang['import_style_file'], $this -> appCore -> drawFileUpload( 'data_file'), $this -> appCore -> lang['import_style_file_expl']);
		echo $this -> appCore -> output -> formItem( $this -> appCore -> lang['style_form_parent'], $this -> appCore -> drawList( 'style_parent', $this -> appCore -> getStyles( true, $this -> api -> style_id), $this -> api -> style_parent));
		echo $this -> appCore -> output -> formItem( $this -> appCore -> lang['style_form_imageset'], $this -> appCore -> drawList( 'style_imageset', $this -> imagesets, $this -> api -> imageset_id));
	
		// Draw Submit Button
		echo $this -> appCore -> output -> submitButton( $this -> appCore -> lang['import_data']);
		
		// Close Block
		echo $this -> appCore -> output -> closeFormBlock();
		
		// Close Form
		echo $this -> appCore -> output -> closeForm();
		
		// Draw output
		$this -> appCore -> output -> draw( $this -> appCore -> lang['acp_import_style'], array(
			$this -> appCore -> adminLink( 'act=imp_style') => $this -> appCore -> lang['acp_import_style'],
		), ob_get_clean());
				
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Performs compilation of style templates
	 *
	 * @param integer $style_id
	 */
	
	function resynchStyle( $style_id){
		
		// If style directory doesnt exists, create it
		if ( !file_exists( STYLES_DATA_PATH . 'style_' . $style_id . '/index.html'))
		{
			class_files::newDir( STYLES_DATA_PATH . 'style_' . $style_id);
		}
		
		// Get style parents
		$style_parents = $this -> appCore -> getStyleParents( $style_id);
		
		// Select Templates Groups from DB
		$this -> appCore -> db -> query( 'SELECT DISTINCT template_group
		FROM ' . DB_PREFIX . 'styles_templates
		WHERE style_id IN (' . join( ',', $style_parents) . ')');
		
		// Compile Template Groups
		while ( $group_result = $this -> appCore -> db -> fetch_array())
		{
			// Create Compiler
			$tpl_compiler = new class_template_compiler( $this -> appCore, $style_id, $style_parents, $group_result[0]);
			
			// Compile template to specified location
			$tpl_compiler -> compile( STYLES_DATA_PATH . 'style_' . $style_id . '/tpl_' . $this -> appCore -> secureFileName( $group_result[0]). PHP_EXT);	
		}
		
	}
	
}